package org.altervista.cp.microkernel;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Properties;

import javax.naming.Context;

import org.altervista.cp.microkernel.install.InstallManager;
import org.altervista.cp.microkernel.util.ClassLoaderUtils;

final class BootstrapProperties {

	static String getInstallManagerClassName() {
		return boostrapProperties.getProperty(InstallManager.class.getName()
				+ ".class", DefaultInstallManager.class.getName());
	}

	static String getKernelEngineClassName() {
		return boostrapProperties.getProperty(KernelEngine.class.getName()
				+ ".class");
	}

	static String getJNDIInitialContextFactory() {
		return boostrapProperties.getProperty(Context.INITIAL_CONTEXT_FACTORY);
	}

	static String getJNDIProviderUrl() {
		return boostrapProperties.getProperty(Context.PROVIDER_URL);
	}

	static String getJNDISecurityPrincipal() {
		return boostrapProperties.getProperty(Context.SECURITY_PRINCIPAL);
	}

	static String getJNDISecurityCredentials() {
		return boostrapProperties.getProperty(Context.SECURITY_CREDENTIALS);
	}

	static String getDataSourceName() {
		return boostrapProperties.getProperty("kernel.jdbc.dsname");
	}

	static String getJDBCDriver() {
		return boostrapProperties.getProperty("kernel.jdbc.driver");
	}

	static String getJDBCUrl() {
		return boostrapProperties.getProperty("kernel.jdbc.url");
	}

	static String getJDBCUser() {
		return boostrapProperties.getProperty("kernel.jdbc.user");
	}

	static String getJDBCPassword() {
		return boostrapProperties.getProperty("kernel.jdbc.password");
	}

	static String getWorkingDirectoryPath() {
		return boostrapProperties.getProperty("kernel.workingdir.path");
	}

	static String getTransactionType() {
		return boostrapProperties.getProperty("kernel.transaction.type",
				"jdbc", new String[] { "container", "jta", "jdbc" });
	}

	static String getUserTransactionName() {
		return boostrapProperties.getProperty("kernel.transaction.type",
				"jdbc", new String[] { "container", "jta", "jdbc" });
	}

	private static final BootProperties boostrapProperties = new BootProperties();

	private static class BootProperties extends Properties {
		private static final long serialVersionUID = 1L;

		public String getProperty(String key, String defaultValue,
				String[] acceptedValues) {
			String value = getProperty(key);
			if (value == null)
				return defaultValue;
			for (String av : acceptedValues) {
				if (av.equals(value))
					return value;
			}
			throw new IllegalArgumentException("Property " + key
					+ " contains the invalid value '" + value
					+ "': accepted are " + Arrays.toString(acceptedValues));
		}

		public String getProperty(String key, String defaultValue) {
			String value = getProperty(key);
			return value == null ? defaultValue : value;
		}

		public synchronized Object put(Object key, Object value) {
			if (containsKey(key)) {
				return null;
			} else {
				return super.put(key, value);
			}
		}
	}

	static {
		InputStream is = null;
		try {
			URL boostrapPropertiesURL = ClassLoaderUtils
					.lookupResource("bootstrap.properties");
			if (boostrapPropertiesURL != null) {
				is = boostrapPropertiesURL.openStream();
				boostrapProperties.load(is);
			}
			boostrapProperties.putAll(System.getProperties());
		} catch (IOException e) {
			throw new IllegalStateException(e);
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
				}
			}
		}
	}

}
